home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dicehelp / SearchRefs.asm < prev    next >
Assembly Source File  |  1995-12-24  |  7KB  |  200 lines

  1. **
  2. **      $Id: SearchRefs.asm,v 30.0 1994/06/10 18:05:50 dice Exp $
  3. **
  4. **      Search loaded reference file for reference.  Search is "best match"
  5. **      for case: an exact match will return instantly.  An inexact match
  6. **      will scan to the end looking for a better option.
  7. **
  8. **          :TODO: Investigate full international case sensitivity issues.
  9. **                 We already do 90%.
  10. **
  11. **              Disallow tabs in search string
  12. **
  13. **              Could do "fast path" search of first char.  25 in 26 would
  14. **              hit it.  Or maybe a BCPL-ish string length.
  15. **
  16. **      (C) Copyright 1992, Obvious Implementations, All Rights Reserved
  17. **
  18.  
  19.                 XDEF    _searchMe
  20.                 XDEF    _convertFile
  21.                 XDEF    _nextLine
  22.  
  23. LF              EQU     10
  24. TAB             EQU     9
  25. FF              EQU     12
  26.  
  27. SKIPNL          MACRO   \1
  28. LP\@            tst.b   (\1)+
  29.                 bne.s   LP\@
  30.                 ENDM
  31.  
  32.         section text,code
  33.  
  34. ;
  35. ; FUNCTION
  36. ;       Return a newline separated file, line-by-line.
  37. ;
  38. ; INPUTS
  39. ;       4(SP)  -Pointer to current index
  40. ;
  41. ; RESULTS
  42. ;       D0     -Length of current line.  Zero for end
  43. ;
  44. _nextLine:      moveq   #FF+1,d1        ;Pass anything numerically above FF without comment
  45.                 move.l  4(sp),a0
  46.                 move.l  a0,a1
  47.  
  48. nl_loop:        cmp.b   (a1)+,d1
  49.                 bcs.s   nl_loop
  50.                 move.b  -1(a1),d0
  51.                 beq.s   nl_end
  52.                 cmp.b   #FF,d0
  53.                 bne.s   nl_noff
  54.                 move.b  #LF,-1(a1)      ;Replace FF with LF
  55. nl_noff:        cmp.b   #LF,d0
  56.                 bne.s   nl_loop
  57.  
  58.                 suba.l  a0,a1
  59.                 move.l  a1,d0
  60.                 rts                     ;exit _nextLine
  61.  
  62. nl_end:         subq.l  #1,a1           ;Don't write NULL
  63.                 suba.l  a0,a1
  64.                 move.l  a1,d0
  65.                 rts                     ;exit _nextLine
  66.  
  67. ;
  68. ; INPUTS
  69. ;       4(SP)   File pointer
  70. ;       8(SP)   Length.  Will stick two NULLs *after* the end
  71. ;
  72. _convertFile:   move.l  4(sp),a0
  73.                 move.l  8(sp),d0
  74.                 moveq   #LF,d1          ;Convert newlines to nulls
  75.  
  76. cf_lp:          cmp.b   (a0)+,d1
  77.                 bne.s   cf_nolf
  78.                 clr.b   -1(a0)
  79. cf_nolf:        subq.l  #1,d0
  80.                 bne.s   cf_lp
  81.  
  82.                 clr.b   (a0)+
  83.                 clr.b   (a0)+
  84.                 rts
  85.  
  86.  
  87. ;
  88. ; INPUTS
  89. ;       D0 - Length of string array. Last entry *must* be LF terminated.
  90. ;       A0 - Pointer to array of strings
  91. ;       A1 - Search string
  92. ;       A2 - Address of pointer to current filename string, filled in.
  93. ;
  94. ; RESULTS
  95. ;       D0 - Pointer to proper string
  96. ;      &A2 - Last matched filename
  97. ;
  98. ; REGISTERS
  99. ;      &A2 - Last matched filename
  100. ;       A3 - Current index
  101. ;       A5 - Search string
  102. ;       D2 - scratch
  103. ;       D3 - <tab>
  104. ;       D4 - Last matched name pointer
  105. ;       D5 - Last matched Inacuracy index
  106. ;       D6 - Current filename
  107. ;       D7 - #$20 for case-match
  108. ;
  109. ;
  110. ;       char * searchMe(char *strings,char *searchfor,&filename,ULONG length);
  111. STACKOFFSET     EQU     11*4
  112. _searchMe:      movem.l d2-d7/a2-a6,-(sp)
  113.  
  114. ;---------------Register setup
  115.                 moveq   #TAB,D3         ;<tab> for quick searches
  116.                 moveq   #0,d4           ;Matched entry
  117.                 moveq   #-1,d5          ;Infinite inaccuary index
  118.                 moveq   #0,d6           ;In case no filenames found...
  119.                 moveq   #~($20),d7         ;Setup for case search
  120.  
  121.                 move.l  STACKOFFSET+4(sp),a3    ;Main index
  122.                 move.l  STACKOFFSET+8(sp),a5    ;Search string
  123.                 move.l  STACKOFFSET+12(sp),a2   ;&filename pointer
  124.                 clr.l   (a2)                    ;No filenmae yet
  125.  
  126.                 move.l  a5,d0                   ;Test for NULL search string
  127.                 beq     sm_alldone
  128.  
  129. ;---------------Main loop
  130.                 bra.s   sm_skipSKIPNL
  131. sm_newname:     move.l  a3,d6           ;Set new name pointer
  132. sm_toploop:     SKIPNL  a3
  133. sm_skipSKIPNL:  move.b  (a3),d2
  134.                 beq.s   sm_alldone      ;Double NULL indicates end...
  135.                 cmp.b   #'~',d2         ;Check for ~ prefex
  136.                 beq.s   sm_newname
  137.  
  138.                 ; Compare current string, case insensitive.  Each character
  139.                 ; of a case-insensitive match adds 1 to the inaccuracy index.
  140.                 ; A zero index ends the search, else the best is used.
  141.                 ;
  142.                 ; A simple folding search is used; while this results in
  143.                 ; some false matches, such a y-umlaut to sharffe-S, we don't
  144.                 ; really care.  Any match is better than no match, and the
  145.                 ; inaccuracy index will weed out the better choice anyway.
  146.                 ;
  147. sm_notaname:    move.l  a5,a0           ;Search string
  148.                 move.l  a3,a1           ;Stash current index, in case of match
  149.                 moveq   #0,d1           ;Zero inaccuary index
  150.  
  151. sm_nextchar:    move.b  (a0)+,d0
  152.                 beq.s   sm_endsource    ;End of search string...
  153.                 move.b  (a3)+,d2
  154.                 cmp.b   d3,d2
  155.                 beq.s   sm_endcandid    ;End of candidate string....
  156.                 cmp.b   d2,d0
  157.                 beq.s   sm_nextchar     ;Match!
  158.                 addq.w  #1,d1           ;Increase inaccuracy
  159.                 and.b   d7,d0           ;Simple folding search
  160.                 and.b   d7,d2           ;Simple folding search
  161.                 cmp.b   d2,d0
  162.                 beq.s   sm_nextchar     ;Match!
  163.                 bra.s   sm_toploop      ;We struck out...
  164.  
  165.                 ; Source string has ended.  Count inaccuacy of 2 for each
  166.                 ; remaining character in the candidate string.
  167.                 ;
  168. sm_endsource:   cmp.b   (a3)+,d3
  169.                 beq.s   sm_endmatch
  170.                 addq.w  #2,d1           ;Increase inaccuracy
  171.                 bra.s   sm_endsource
  172.  
  173.                 ; Candidate string has ended.  Count inaccuacy of 2 for each
  174.                 ; remaining character in the source string.
  175.                 ;
  176. sm_endcandid:   addq.w  #2,d1           ;Increase inaccuracy
  177.                 tst.b   (a0)+
  178.                 bne.s   sm_endcandid
  179.  
  180.                 ; We have a match.  Update pointers if better than our last
  181.                 ; match.
  182.                 ;
  183. sm_endmatch:    cmp.l   d5,d1           ;Current inaccuary index to old
  184.                 bcc.s   sm_toploop      ;Keep searching for perfection...
  185.                 move.l  d6,(a2)         ;Got one!  Stash filename.
  186.                 move.l  a1,d4           ;Got one!  Stash pointer.
  187.                 move.l  d1,d5           ;Got one!  Stash inaccuracy index.
  188.                 bne.s   sm_toploop      ;Keep searching for perfection...
  189.  
  190.  
  191.                 ; All done.  At this point we have nothing, a perfect match
  192.                 ; or a partial match.  Tell the world.
  193.                 ;
  194. sm_alldone:     move.l  d4,d0           ;Return what we found
  195.                 ;[&A2 - pointer to current filename]
  196.  
  197.                 movem.l (sp)+,d2-d7/a2-a6
  198.                 rts
  199.         end
  200.